package com.hsjk.szwj.module.pay.controller.admin.division;

import cn.hutool.extra.spring.SpringUtil;
import com.hsjk.szwj.framework.common.constant.CommonConstant;
import com.hsjk.szwj.framework.common.exception.ServiceException;
import com.hsjk.szwj.framework.common.exception.enums.GlobalErrorCodeConstants;
import com.hsjk.szwj.framework.common.pojo.CommonResult;
import com.hsjk.szwj.module.pay.controller.PayApiController;
import com.hsjk.szwj.module.pay.controller.admin.division.vo.AdminDivisionAccountTypeReqVO;
import com.hsjk.szwj.module.pay.controller.admin.division.vo.AdminDivisionAccountTypeRespVO;
import com.hsjk.szwj.module.pay.controller.app.division.vo.DivisionReceiverBindReqVO;
import com.hsjk.szwj.module.pay.controller.app.division.vo.DivisionReceiverBindRespVO;
import com.hsjk.szwj.module.pay.dal.dataobject.CommonPayResult;
import com.hsjk.szwj.module.pay.dal.dataobject.config.ChannelRetMsg;
import com.hsjk.szwj.module.pay.dal.dataobject.config.MchAppConfigContext;
import com.hsjk.szwj.module.pay.dal.dataobject.division.MchDivisionReceiverDO;
import com.hsjk.szwj.module.pay.dal.dataobject.division.MchDivisionReceiverGroupDO;
import com.hsjk.szwj.module.pay.dal.dataobject.system.MchAppDO;
import com.hsjk.szwj.module.pay.dal.dataobject.system.MchInfoDO;
import com.hsjk.szwj.module.pay.service.ConfigContextQueryService;
import com.hsjk.szwj.module.pay.service.IDivisionService;
import com.hsjk.szwj.module.pay.service.IMchAppService;
import com.hsjk.szwj.module.pay.service.IMchInfoService;
import com.hsjk.szwj.module.pay.service.MchDivisionReceiverGroupService;
import com.hsjk.szwj.module.pay.service.MchDivisionReceiverService;
import com.hsjk.szwj.module.pay.service.PayInterfaceConfigService;
import com.hsjk.szwj.module.pay.service.PayInterfaceDefineService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.List;

import static com.hsjk.szwj.framework.common.pojo.CommonResult.success;

/**
 * @author chenjiawei
 * @desc
 * @Date 2023/09/06 11:27
 **/
@Tag(name = "后台 - 分账账号绑定相关接口")
@RestController
@RequestMapping("/division")
@Validated
@Slf4j
public class AdminMchDivisionController extends PayApiController {
    @Resource
    private ConfigContextQueryService configContextQueryService;
    @Resource
    private PayInterfaceConfigService payInterfaceConfigService;
    @Resource
    private MchDivisionReceiverService mchDivisionReceiverService;
    @Resource
    private MchDivisionReceiverGroupService mchDivisionReceiverGroupService;
    @Resource
    private PayInterfaceDefineService payInterfaceDefineService;
    @Resource
    private IMchInfoService mchInfoService;
    @Resource
    private IMchAppService mchAppService;

    @Resource
    private IDivisionService divisionService;

    @PostMapping("/list-receiver")
    @Operation(summary = "获取已经绑定的分账账户信息")
    @PreAuthorize("@ss.hasPermission('pay:division:query')")
    public CommonResult<List<AdminDivisionAccountTypeRespVO>> getAdminDivisionAccountInfo(@RequestBody @Validated AdminDivisionAccountTypeReqVO reqVO) {
        return success(divisionService.getAdminDivisionAccountInfo(reqVO));
    }

    /**
     * 分账账号绑定
     **/
    @PostMapping("/bind-receiver")
    @Operation(summary = "绑定分账账户信息")
//    @PreAuthorize("@ss.hasPermission('pay:division:add')")
    public CommonPayResult divisionBind(@RequestBody @Validated DivisionReceiverBindReqVO bizRQ) {
        try {

            //检查商户应用是否存在该接口
            Long ifId = payInterfaceDefineService.getIdByCode(bizRQ.getIfCode());

            String ifCode = bizRQ.getIfCode();
            MchInfoDO mchInfoDO = mchInfoService.getMchInfoByTenant();
            MchAppDO mchAppDO = mchAppService.getById(bizRQ.getAppId());
            Long mchId = mchInfoDO.getId();
            Long appId = mchAppDO.getId();
            // 商户配置信息
            MchAppConfigContext mchAppConfigContext =
                    configContextQueryService.queryMchInfoAndAppInfo(mchId,
                            appId);
            if (mchAppConfigContext == null) {
                throw new ServiceException(GlobalErrorCodeConstants.BAD_REQUEST.getCode(),
                        "获取商户应用信息失败");
            }

            MchInfoDO mchInfo = mchAppConfigContext.getMchInfo();

            if (!payInterfaceConfigService.mchAppHasAvailableIfCode(mchAppDO.getId(), ifId)) {
                throw new ServiceException(GlobalErrorCodeConstants.BAD_REQUEST.getCode(),
                        "商户应用的支付配置不存在或已关闭");
            }
            MchDivisionReceiverGroupDO group
                    = mchDivisionReceiverGroupService
                    .findByIdAndMchNo(bizRQ.getReceiverGroupId(), mchInfo.getMchNo());
            if (group == null) {
                throw new ServiceException(GlobalErrorCodeConstants.BAD_REQUEST.getCode(),
                        "商户分账账号组不存在，请检查或进入商户平台进行创建操作");
            }

            //生成数据库对象信息 （数据不完成， 暂时不可入库操作）
            MchDivisionReceiverDO receiver = genRecord(bizRQ, group, mchInfo, ifCode, mchAppDO);

            //调起上游接口

            IDivisionService divisionService =
                    SpringUtil.getBean(ifCode + "DivisionService", IDivisionService.class);
            if (divisionService == null) {
                throw new ServiceException(GlobalErrorCodeConstants.BAD_REQUEST.getCode(),
                        "系统不支持该分账接口");
            }

            ChannelRetMsg retMsg = divisionService.bind(receiver, mchAppConfigContext);
            if (retMsg.getChannelState() == ChannelRetMsg.ChannelState.CONFIRM_SUCCESS) {

                receiver.setState(CommonConstant.YES);
                receiver.setBindSuccessTime(LocalDateTime.now());
                mchDivisionReceiverService.save(receiver);

            } else {

                receiver.setState(CommonConstant.NO);
                receiver.setChannelBindResult(retMsg.getChannelErrMsg());
            }

            DivisionReceiverBindRespVO bizRes =
                    DivisionReceiverBindRespVO.buildByRecord(receiver);

            if (retMsg.getChannelState() == ChannelRetMsg.ChannelState.CONFIRM_SUCCESS) {
                bizRes.setBindState(CommonConstant.YES);
            } else {
                bizRes.setBindState(CommonConstant.NO);
                bizRes.setErrCode(retMsg.getChannelErrCode());
                bizRes.setErrMsg(retMsg.getChannelErrMsg());
            }

            return CommonPayResult.okWithSign(bizRes,
                    mchAppConfigContext.getMchApp().getAppSecret());

        } catch (ServiceException e) {
            return CommonPayResult.error(e.getMessage());

        } catch (Exception e) {
            log.error("系统异常：{}", e);
            return CommonPayResult.error("系统异常");
        }
    }

    private MchDivisionReceiverDO genRecord(DivisionReceiverBindReqVO bizRQ,
                                            MchDivisionReceiverGroupDO group,
                                            MchInfoDO mchInfo,
                                            String ifCode, MchAppDO mchApp) {
        MchDivisionReceiverDO receiver = new MchDivisionReceiverDO();
        //别名
        receiver.setReceiverAlias(StringUtils.defaultIfEmpty(bizRQ.getReceiverAlias(), bizRQ.getAccNo()));
        //分组ID
        receiver.setReceiverGroupId(bizRQ.getReceiverGroupId());
        //组名称
        receiver.setReceiverGroupName(group.getReceiverGroupName());
        //商户号
        receiver.setMchId(mchInfo.getId());
        //isvNo
        receiver.setIsvId(mchInfo.getIsvId());
        //appId
        receiver.setAppId(mchApp.getId());
        //接口代码
        receiver.setIfCode(ifCode);
        //账号类型
        receiver.setAccType(bizRQ.getAccType());
        //账号
        receiver.setAccNo(bizRQ.getAccNo());
        //账号名称
        receiver.setAccName(bizRQ.getAccName());
        //关系
        receiver.setRelationType(bizRQ.getRelationType());
        //关系名称
        receiver.setRelationTypeName(getRelationTypeName(bizRQ.getRelationType()));

        if (receiver.getRelationTypeName() == null) {
            receiver.setRelationTypeName(bizRQ.getRelationTypeName());
        }
        //分账比例
//        receiver.setDivisionProfit(divisionProfit);
        //渠道信息
        receiver.setChannelExtInfo(bizRQ.getChannelExtInfo());

        return receiver;
    }

    public String getRelationTypeName(String relationType) {

        if ("PARTNER".equals(relationType)) {
            return "合作伙伴";
        } else if ("SERVICE_PROVIDER".equals(relationType)) {
            return "服务商";
        } else if ("STORE".equals(relationType)) {
            return "门店";
        } else if ("STAFF".equals(relationType)) {
            return "员工";
        } else if ("STORE_OWNER".equals(relationType)) {
            return "店主";
        } else if ("HEADQUARTER".equals(relationType)) {
            return "总部";
        } else if ("BRAND".equals(relationType)) {
            return "品牌方";
        } else if ("DISTRIBUTOR".equals(relationType)) {
            return "分销商";
        } else if ("USER".equals(relationType)) {
            return "用户";
        } else if ("SUPPLIER".equals(relationType)) {
            return "供应商";
        }
        return null;
    }
}
